﻿using CommunicaionLib;
using CommunicaionLib.helper;
using CommunicaionLib.Interface;
using CommunicaionLib.Model;
using PlcLib.Model;
using PLCLib.Base;
using PLCLib.Interface;
using PLCLib.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PLCLib
{
    /* 本例中，Ormon采用HostLink协议
    * 握手发送：46 49 4E 53   00 00 00 10   00 00 00 01   00 00 00 00 00 00 00 01  00 00 00 65
    * 握手回复：
    * 
    * 读示例：46494E53 0000001A 00000002 00000000 80000200 01000034 00FF0101 82 0000 00 0002
    * 读回复(34个字节)：46 49 4E 53 00 00 00 1A 00 00 00 02 00 00 00 00 C0 00 02 00 34 00 00 01 00 FF 01 01 00 00  00 14 00 1E
    * 
    * 写示例
    * 
    * 发送：46494E53 0000001D 00000002 00000000 80000200 01000034 00FF0102 82 0002 00 0002 4148 0000
    * 接收 46 49 4E 53 00 00 00 16 00 00 00 02 00 00 00 00 C0 00 02 00 34 00 00 01 00 00 01 02 00 00  (30个字节)
    */
    public class OrmonPlc : PlcBase
    {
        private Net net;

        public override event Action<object, PlcEventArgs> OnMessage;
        public override event Action<object, PlcEventArgs> OnError;
        public override event Action<object, DataPackage> OnSend;
        public override event Action<object, DataPackage> OnReceived;
        public override void Initialize(Net net)
        {
            this.net = net;
            communication.Initiallize(IPAddress.Parse(net.IP), net.Port);
            Init();
        }

        public override void Initialize(Port port)
        {
            communication.Initiallize(port.Name, port.BaudRate);
            Init();
        }

        private void Init()
        {
            //todo 执行一些OrmonPlc的初始化工作
            ConnectedState = Enums.ConnectedState.连接中;
            OnMessage?.Invoke(this, new PlcEventArgs { Message = "开始连接" });
            bool connectResult = Connect();
            if (!connectResult)
            {
                for (int i = 0; i < 10; i++)
                {
                    connectResult = Connect();
                    if (connectResult)
                    {
                        break;
                    }
                    if (i == 9)
                    {
                        OnMessage?.Invoke(this, new PlcEventArgs { Message = "请重启设备" });
                        return;
                    }
                }
            }

            ConnectedState = Enums.ConnectedState.通讯正常;
        }

        private bool Connect()
        {
            bool result = false;
            ConnectionResult connectionResult = communication.Connect();
            if (connectionResult.Success)
            {
                OnMessage?.Invoke(this, new PlcEventArgs { Message = "连接成功" });
                ConnectedState = Enums.ConnectedState.连接成功;

#if DEBUG
                result = true;//握手操作
#endif
                if (!result)
                {
                    result = ShakeHands();//握手操作
                }
            }
            else
            {
                OnMessage?.Invoke(this, new PlcEventArgs { Message = "连接失败" });
                ConnectedState = Enums.ConnectedState.连接失败;
                result = false;
            }

            return result;
        }

        /// <summary>
        /// 与欧姆龙下位机PLC握手
        /// </summary>
        /// <returns></returns>
        private bool ShakeHands()
        {
            //127.0.0.1 上位机
            //192.168.1.101 下位机

            bool result = false;
            var lastNode = net.LocalIPAddress.GetAddressBytes().Last();
            var finsBytes = ByteHelper.GetShakeByte(lastNode);
            ConnectionResult connectionResult = communication.ShakeHands(finsBytes);//握手
            OnSend?.Invoke(this, new DataPackage { SendBuffer = finsBytes, SendTime = DateTime.Now, CommandNumber = 0 });
            if (connectionResult.Success == false)
            {
                //todo

                return result;
            }
            /*
             * 发送指令：46494E53 抬头0000000C长度 00000000 命令 00000000错误代码 00000034客户机节点（电脑的IP尾数16进制）
             * 接收指令：46 49 4E 53   00 00 00 10   00 00 00 01   00 00 00 00 00000034客户机节点地址  00000001服务器地址
             * 测试代码：46 49 4E 53   00 00 00 10   00 00 00 01   00 00 00 00   00 00 00 01  00 00 00 65 （6组）
             */
            //握手成功
            byte[] receiveBytes = connectionResult.Content as byte[] ?? new byte[0];
            OnReceived?.Invoke(this, new DataPackage { ReceiveBuffer = receiveBytes, ReceiveTime = DateTime.Now, CommandNumber = 0 });

            if (receiveBytes.Length == 24)
            {
                if (receiveBytes[8] != 0x00
                    || receiveBytes[9] != 0x00
                    || receiveBytes[10] != 0x00
                    || receiveBytes[11] != 0x01
                    || receiveBytes[12] != 0x00
                    || receiveBytes[13] != 0x00
                    || receiveBytes[14] != 0x00
                    || receiveBytes[15] != 0x00)
                {
                    OnError?.Invoke(this, new PlcEventArgs { Message = "握手时校验失败" });
                    return result;
                }

                result = true;
            }
            else
            {
                ConnectedState = Enums.ConnectedState.握手失败;
                OnError?.Invoke(this, new PlcEventArgs { Message = $"握手回复字节长度不对,当前接收长度={receiveBytes.Length}" });
                return result;
            }

            return result;
        }

        public override IPlcResult Start(Action action = null)
        {
            IPlcResult plcResult = new OrmonResult();
            if (ConnectedState == Enums.ConnectedState.通讯正常)
            {
                OnMessage?.Invoke(this, new PlcEventArgs { Message = "初始化完成" });

            }
            else
            {
                plcResult.Message = "初始化未完成";
                plcResult.Success = false;
                OnError?.Invoke(this, new PlcEventArgs { Message = plcResult.Message });
                return plcResult;
            }

            communication.OnReceived += Communication_OnReceived;//订阅接收数据事件
            communication.OnError += Communication_OnError;//订阅错误数据事件
            var result = communication.Start();//通讯层开始工作
            if (!result)
            {
                plcResult.Message = "通讯层开始失败";
                plcResult.Success = false;
                OnError?.Invoke(this, new PlcEventArgs { Message = plcResult.Message });
                return plcResult;
            }

            Task.Factory.StartNew(SendThread);//最后启动下发指令线程
            plcResult.Success = true;
            plcResult.Message = "PLC成功开始工作";
            OnMessage?.Invoke(this, new PlcEventArgs { Message = plcResult.Message });

            if (action != null)
            {
                Task.Factory.StartNew(action);//提前写入PLC预设参数
            }

            return plcResult;
        }

        //接收通讯层错误的回调函数
        private void Communication_OnError(object arg1, CommunicationArgsBase arg)
        {
            OnError?.Invoke(this, new PlcEventArgs { Exception = arg.Exception, Message = arg.Message });
        }

        //接收通讯层数据的回调函数
        private void Communication_OnReceived(object arg1, DataPackage package)
        {
            lock (receiveLocker)
            {
                receivePackages.Add(package);
            }

            OnReceived?.Invoke(this, package);

            //todo 松开消费线程中的sendWaiter同步器
            sendWaiter.Set();
        }

        private void SendThread()
        {
            while (!cancellationTokenSource.IsCancellationRequested)
            {
                DataPackage package;

                if (sendPackages.Count > 0)
                {
                    lock (sendLocker)
                    {
                        package = sendPackages.Dequeue();//从队列中取出一条指令(数据包)
                    }
                }
                else
                {
                    Task.Delay(1).Wait();
                    continue;
                }

                var result = false;
                for (int i = 0; i < 3; i++)
                {
                    package.SendTimes++;
                    package.SendTime = DateTime.Now;
                    communication.Send(package);//发送数据包
                    OnSend?.Invoke(this, package);//触发数据发送事件
                    result = sendWaiter.WaitOne(net.MaxMilliseconds);//阻塞
                    if (result)
                    {
                        break;
                    }
                }

                //如果result不为真，
                if (!result)
                {
                    ConnectedState = Enums.ConnectedState.通讯中断;

                    //todo  要么重接连接 要么提示
                }
                else
                {
                    ConnectedState = Enums.ConnectedState.通讯正常;
                }
            }
        }

        /// <summary>
        /// 入队
        /// </summary>
        /// <param name="package"></param>
        private void Enqueue(DataPackage package)
        {
            lock (sendLocker)
            {
                sendPackages.Enqueue(package);
            }
        }

        public override IPlcResult Read(Command command)
        {
            IPlcResult result = new OrmonResult();
            result.Command = command;
            DataPackage package = new DataPackage();
            package.CreateTime = DateTime.Now;
            package.CommandNumber = GetCommandNumber();
            package.SendBuffer = command.GetReadBuffer(this.net, package.CommandNumber);
            package.NeedLength = 30 + command.Length * 2;
            Enqueue(package);

            //等待回复
            Stopwatch stopwatch = Stopwatch.StartNew();
            DataPackage receive = new DataPackage();
            while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
            {
                lock (receiveLocker)
                {
                    receive = receivePackages.Find(item => item.CommandNumber == package.CommandNumber);
                    if (receive.CommandNumber > 0)
                    {
                        receivePackages.Remove(receive);
                        package.FinishTime = DateTime.Now;
                    }
                }

                if (receive.CommandNumber > 0) break;

                Thread.Sleep(1);
            }

            if (receive.ReceiveBuffer != null)
            {
                package.SendTime = receive.SendTime;
                package.ReceiveTime = receive.ReceiveTime;
                package.ReceiveBuffer = receive.ReceiveBuffer;
                result.ReceiveBuffer = receive.ReceiveBuffer;
                result.Success = true;
            }
            Writelog(command, package, result);
            return result;
        }



        public override async Task<IPlcResult> ReadAsync(Command command)
        {
            var task = new Task<IPlcResult>(() =>
            {
                IPlcResult result = new OrmonResult();
                result.Command = command;
                DataPackage package = new DataPackage();
                package.CreateTime = DateTime.Now;
                package.CommandNumber = GetCommandNumber();
                package.SendBuffer = command.GetReadBuffer(this.net, package.CommandNumber);
                package.NeedLength = 30 + command.Length * 2;
                Enqueue(package);

                //等待回复
                Stopwatch stopwatch = Stopwatch.StartNew();
                DataPackage receive = new DataPackage();
                while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
                {
                    lock (receiveLocker)
                    {
                        receive = receivePackages.Find(item => item.CommandNumber == package.CommandNumber);
                        if (receive.CommandNumber > 0)
                        {
                            receivePackages.Remove(receive);
                            package.FinishTime = DateTime.Now;
                        }
                    }

                    if (receive.CommandNumber > 0) break;

                    Thread.Sleep(1);
                }

                if (receive.ReceiveBuffer != null)
                {
                    package.SendTime = receive.SendTime;
                    package.ReceiveTime = receive.ReceiveTime;
                    package.ReceiveBuffer = receive.ReceiveBuffer;
                    result.ReceiveBuffer = receive.ReceiveBuffer;
                    result.Success = true;
                }
                Writelog(command, package, result);
                return result;
            });

            task.Start();

            return await task;
        }

        public override IPlcResult Send(byte[] array)
        {
            OrmonResult result = new OrmonResult();
            var package = new DataPackage();
            package.CreateTime = DateTime.Now;
            package.CommandNumber = GetCommandNumber();
            package.SendBuffer = array;
            package.NeedLength = -1;//-1表示不按长度获取下位机回复
            Enqueue(package);

            //等待回复
            Stopwatch stopwatch = Stopwatch.StartNew();
            DataPackage receive = new DataPackage();
            while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
            {
                lock (receiveLocker)
                {
                    receive = receivePackages.Find(item => item.CommandNumber == package.CommandNumber);
                    if (receive.CommandNumber > 0)
                    {
                        receivePackages.Remove(receive);
                        package.FinishTime = DateTime.Now;
                    }
                }

                if (receive.CommandNumber > 0) break;

                Thread.Sleep(1);
            }

            if (receive.ReceiveBuffer != null)
            {
                package.SendTime = receive.SendTime;
                package.ReceiveTime = receive.ReceiveTime;
                package.ReceiveBuffer = receive.ReceiveBuffer;
                result.ReceiveBuffer = receive.ReceiveBuffer;
                result.Success = true;
            }
            return result;
        }

        public override async Task<IPlcResult> SendAsync(byte[] array)
        {
            var task = new Task<IPlcResult>(() =>
            {
                OrmonResult result = new OrmonResult();
                var package = new DataPackage();
                package.CreateTime = DateTime.Now;
                package.CommandNumber = GetCommandNumber();
                package.SendBuffer = array;
                package.NeedLength = -1;//-1表示不按长度获取下位机回复
                Enqueue(package);

                //等待回复
                Stopwatch stopwatch = Stopwatch.StartNew();
                DataPackage receive = new DataPackage();
                while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
                {
                    lock (receiveLocker)
                    {
                        receive = receivePackages.Find(item => item.CommandNumber == package.CommandNumber);
                        if (receive.CommandNumber > 0)
                        {
                            receivePackages.Remove(receive);
                            package.FinishTime = DateTime.Now;
                        }
                    }

                    if (receive.CommandNumber > 0) break;

                    Thread.Sleep(1);
                }

                if (receive.ReceiveBuffer != null)
                {
                    package.SendTime = receive.SendTime;
                    package.ReceiveTime = receive.ReceiveTime;
                    package.ReceiveBuffer = receive.ReceiveBuffer;
                    result.ReceiveBuffer = receive.ReceiveBuffer;
                    result.Success = true;
                }

                return result;
            });

            task.Start();

            return await task;
        }

        public override IPlcResult Write(Command command, int data)
        {
            //下发指令
            IPlcResult result = new OrmonResult() { Command = command };
            DataPackage package = new DataPackage();
            package.CreateTime = DateTime.Now;
            package.CommandNumber = GetCommandNumber();
            package.SendBuffer = command.GetWriteBuffer(net, package.CommandNumber, data);
            package.NeedLength = 30;
            Enqueue(package);

            //等待回复
            Stopwatch stopwatch = Stopwatch.StartNew();
            DataPackage receive = new DataPackage();
            while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
            {
                lock (receiveLocker)
                {
                    receive = receivePackages.Find(item => item.CommandNumber == package.CommandNumber);
                    if (receive.CommandNumber > 0)
                    {
                        receivePackages.Remove(receive);
                        package.FinishTime = DateTime.Now;
                        break;
                    }
                }

                Thread.Sleep(1);
            }

            if (receive.ReceiveBuffer != null)
            {
                package.SendTime = receive.SendTime;
                package.ReceiveTime = receive.ReceiveTime;
                package.ReceiveBuffer = receive.ReceiveBuffer;
                result.ReceiveBuffer = receive.ReceiveBuffer;
                result.Success = true;
            }

            Writelog(command, package, result);
            return result;
        }

        public override async Task<IPlcResult> WriteAsync(Command command, int data)
        {
            var task = new Task<IPlcResult>(() =>
            {
                //下发指令
                IPlcResult result = new OrmonResult() { Command = command };
                DataPackage package = new DataPackage();
                package.CreateTime = DateTime.Now;
                package.CommandNumber = GetCommandNumber();
                package.SendBuffer = command.GetWriteBuffer(net, package.CommandNumber, data);
                package.NeedLength = 30;
                Enqueue(package);

                //等待回复
                Stopwatch stopwatch = Stopwatch.StartNew();
                DataPackage receive = new DataPackage();
                while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
                {
                    lock (receiveLocker)
                    {
                        receive = receivePackages.Find(item => item.CommandNumber == package.CommandNumber);
                        if (receive.CommandNumber > 0)
                        {
                            receivePackages.Remove(receive);
                            package.FinishTime = DateTime.Now;
                            break;
                        }
                    }

                    Thread.Sleep(1);
                }

                if (receive.ReceiveBuffer != null)
                {
                    package.SendTime = receive.SendTime;
                    package.ReceiveTime = receive.ReceiveTime;
                    package.ReceiveBuffer = receive.ReceiveBuffer;
                    result.ReceiveBuffer = receive.ReceiveBuffer;
                    result.Success = true;
                }

                Writelog(command, package, result);
                return result;
            });

            task.Start();

            return await task;
        }

        public override IPlcResult Write(Command command, List<int> data)
        {
            //下发指令
            OrmonResult result = new OrmonResult() { Command = command };
            DataPackage package = new DataPackage();
            package.CreateTime = DateTime.Now;
            package.CommandNumber = GetCommandNumber();
            package.SendBuffer = command.GetWriteBuffer(net, package.CommandNumber, data);
            package.NeedLength = 30;
            Enqueue(package);

            //等待回复
            Stopwatch stopwatch = Stopwatch.StartNew();
            DataPackage receive = new DataPackage();
            while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
            {
                lock (receiveLocker)
                {
                    receive = receivePackages.Find(item => item.CommandNumber == package.CommandNumber);
                    if (receive.CommandNumber > 0)
                    {
                        receivePackages.Remove(receive);
                        package.FinishTime = DateTime.Now;
                        break;
                    }
                }

                Thread.Sleep(1);
            }

            if (receive.ReceiveBuffer != null)
            {
                package.SendTime = receive.SendTime;
                package.ReceiveTime = receive.ReceiveTime;
                package.ReceiveBuffer = receive.ReceiveBuffer;
                result.ReceiveBuffer = receive.ReceiveBuffer;
                result.Success = true;
            }

            Writelog(command, package, result);
            return result;

        }

        public override async Task<IPlcResult> WriteAsync(Command command, List<int> data)
        {
            var task = new Task<IPlcResult>(() =>
            {
                //下发指令
                OrmonResult result = new OrmonResult() { Command = command };
                DataPackage package = new DataPackage();
                package.CreateTime = DateTime.Now;
                package.CommandNumber = GetCommandNumber();
                package.SendBuffer = command.GetWriteBuffer(net, package.CommandNumber, data);
                package.NeedLength = 30;
                Enqueue(package);

                //等待回复
                Stopwatch stopwatch = Stopwatch.StartNew();
                DataPackage receive = new DataPackage();
                while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
                {
                    lock (receiveLocker)
                    {
                        receive = receivePackages.Find(item => item.CommandNumber == package.CommandNumber);
                        if (receive.CommandNumber > 0)
                        {
                            receivePackages.Remove(receive);
                            package.FinishTime = DateTime.Now;
                            break;
                        }
                    }

                    Thread.Sleep(1);
                }

                if (receive.ReceiveBuffer != null)
                {
                    package.SendTime = receive.SendTime;
                    package.ReceiveTime = receive.ReceiveTime;
                    package.ReceiveBuffer = receive.ReceiveBuffer;
                    result.ReceiveBuffer = receive.ReceiveBuffer;
                    result.Success = true;
                }

                Writelog(command, package, result);
                return result;
            });

            task.Start();

            return await task;
        }

        public override IPlcResult<T> Read<T>(Command command)
        {
            //下发指令
            OrmonResult<T> result = new OrmonResult<T>() { Command = command };
            DataPackage package = new DataPackage();
            package.CreateTime = DateTime.Now;
            package.CommandNumber = GetCommandNumber();
            package.SendBuffer = command.GetReadBuffer(net, package.CommandNumber);
            package.NeedLength = GetNeedLength<T>(command.Length);
            Enqueue(package);

            //等待回复
            Stopwatch stopwatch = Stopwatch.StartNew();
            DataPackage receive = new DataPackage();
            while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
            {
                lock (receiveLocker)
                {
                    receive = receivePackages.Find(item => item.CommandNumber == package.CommandNumber);
                    if (receive.CommandNumber > 0)
                    {
                        receivePackages.Remove(receive);
                        package.FinishTime = DateTime.Now;
                        break;
                    }
                }
                Thread.Sleep(1);
            }

            if (receive.ReceiveBuffer != null)
            {
                package.SendTime = receive.SendTime;
                package.ReceiveTime = receive.ReceiveTime;
                package.ReceiveBuffer = receive.ReceiveBuffer;
                result.ReceiveBuffer = receive.ReceiveBuffer;
                result.Success = true;
            }
            Writelog(command, package, result);
            return result;
        }

        public override async Task<IPlcResult<T>> ReadAsync<T>(Command command)
        {
            //返回对象
            OrmonResult<T> result = new OrmonResult<T>() { Command = command };
            await Task.Run(() =>
            {
                DataPackage package = new DataPackage();
                package.CreateTime = DateTime.Now;
                package.CommandNumber = GetCommandNumber();
                package.SendBuffer = command.GetReadBuffer(net, package.CommandNumber);
                //package.NeedLength = 30 + command.Length * 2; //todo 需要优化
                package.NeedLength = GetNeedLength<T>(command.Length);
                Enqueue(package);

                //等待回复
                Stopwatch stopwatch = Stopwatch.StartNew();
                DataPackage receive = new DataPackage();
                while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
                {
                    lock (receiveLocker)
                    {
                        receive = receivePackages.Find(item => item.CommandNumber == package.CommandNumber);
                        if (receive.CommandNumber > 0)
                        {
                            receivePackages.Remove(receive);
                            package.FinishTime = DateTime.Now;
                            break;
                        }
                    }
                    Thread.Sleep(1);
                }

                if (receive.ReceiveBuffer != null)
                {
                    package.SendTime = receive.SendTime;
                    package.ReceiveTime = receive.ReceiveTime;
                    package.ReceiveBuffer = receive.ReceiveBuffer;
                    result.ReceiveBuffer = receive.ReceiveBuffer;
                    result.Success = true;
                }

                Writelog(command, package, result);

            });

            return result;
        }

        public override IPlcResult<T> Write<T>(Command command, T data)
        {
            //返回对象
            OrmonResult<T> result = new OrmonResult<T>() { Command = command };
            //创建数据包
            DataPackage package = new DataPackage();
            package.CreateTime = DateTime.Now;
            package.CommandNumber = GetCommandNumber();
            package.SendBuffer = command.GetWriteBuffer(net, package.CommandNumber, data);
            package.NeedLength = 30;

            if (package.SendBuffer != null && package.SendBuffer.Length > 0)
            {
                Enqueue(package);

                //等待回复
                Stopwatch stopwatch = Stopwatch.StartNew();
                DataPackage receive = new DataPackage();
                while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
                {
                    lock (receiveLocker)
                    {
                        receive = receivePackages.Find(item => item.CommandNumber == package.CommandNumber);
                        if (receive.CommandNumber > 0)
                        {
                            receivePackages.Remove(receive);
                            package.FinishTime = DateTime.Now;
                            break;
                        }
                    }

                    Thread.Sleep(1);
                }

                if (receive.CommandNumber > 0)
                {
                    package.SendTime = receive.SendTime;
                    package.ReceiveTime = receive.ReceiveTime;
                    package.ReceiveBuffer = receive.ReceiveBuffer;
                    result.ReceiveBuffer = receive.ReceiveBuffer;
                    result.Success = true;
                }


            }
            else
            {
                throw new Exception("下发指令数据为空");
            }

            Writelog(command, package, result);

            return result;
        }

        public override async Task<IPlcResult<T>> WriteAsync<T>(Command command, T data)
        {
            throw new NotImplementedException();
        }



        public override void Stop()
        {
            base.Stop();

            //todo 将来还有一些需要在Ormonplc中结束的操作
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="length">字的长度</param>
        /// <returns></returns>
        private int GetNeedLength<T>(int length)
        {
            int result = 30;
            Type type = typeof(T);
            switch (type.FullName)
            {
                case "System.Int16":
                    result += length * 2;
                    break;
                case "System.UInt16":
                    result += length * 2;
                    break;
                case "System.Int32":
                    result += length * 2;
                    break;
                case "System.UInt32":
                    result += length * 2;
                    break;
                case "System.Int16[]":
                    result += length * 2;
                    break;
                case "System.UInt16[]":
                    result += length * 2;
                    break;
                case "System.Int32[]":
                    result += length * 2;
                    break;
                case "System.UInt32[]":
                    result += length * 2;
                    break;
                default:
                    result += length * 2;
                    break;
            }

            return result;
        }

        /// <summary>
        /// 写入数据包生命周期日志
        /// </summary>
        /// <param name="command"></param>
        /// <param name="package"></param>
        /// <param name="result"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void Writelog(Command command, DataPackage package, IPlcResult result)
        {
            if (result == null) return;

            StringBuilder sb = new StringBuilder();
            sb.Append($"序号:{package.CommandNumber} | 发送时间:{package.SendTime} | 回复时间:{package.ReceiveTime} | 耗时: {(package.FinishTime - package.CreateTime).TotalMilliseconds} 毫秒\r");
            sb.Append($"发送:{package.SendBufferToString}\r");
            sb.Append($"接收:{package.ReceiveBufferToString}\r\r");
            Log.Info(sb.ToString());
        }


        /// <summary>
        /// 写入数据包生命周期日志
        /// </summary>
        /// <param name="command"></param>
        /// <param name="package"></param>
        /// <param name="result"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void Writelog<T>(Command command, DataPackage package, IPlcResult<T> result)
        {
            if (result == null) return;

            StringBuilder sb = new StringBuilder();
            sb.Append($"序号:{package.CommandNumber} | 发送时间:{package.SendTime} | 回复时间:{package.ReceiveTime} | 耗时: {(package.FinishTime - package.CreateTime).TotalMilliseconds} 毫秒\r");
            sb.Append($"发送:{package.SendBufferToString}\r");
            sb.Append($"接收:{package.ReceiveBufferToString}\r\r");
            Log.Info(sb.ToString());
        }
    }
}
